#! /usr/bin/python
# -*- coding: utf-8 -*-

#-----------------------------------------------------------------------------
# Name:     QDWL.py
# Purpose:  Quick and Dirty Wikipedia to Latex 
# Author:   Fabien Marteau <fabien.marteau@armadeus.com>
# Created:  03/06/2008
#-----------------------------------------------------------------------------
#  Copyright (2008)  Armadeus Systems
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#-----------------------------------------------------------------------------
# Revision list :
#
# Date       By        Changes
#
# TODO: 
#       - manage links not solved
#       - problem with image to small
#
# Packages required:
#  - curl
#  - pdflatex
#  - texlive-latex-recommended
#-----------------------------------------------------------------------------

__doc__ = """
A little script to convert mediaWiki syntax to Latex, need curl
python QDWL.py latextemplate.tex latexresultfile.tex
"""            
__version__ = "1.0.0"
__versionTime__ = "03/06/2008"
__author__ = "Fabien Marteau <fabien.marteau@armadeus.com>"

import sys # for args
import re  # for regexp
import os  # for launching bash commands : curl
import xml.etree.cElementTree as ET # for xml
import xml.dom.minidom
from xml.dom.minidom import Node
#import ClientCookie # to get wiki page I need cookies

showline=6

cmpt_figure = 1

IMGDIR="img/"

#some functions

def getWikimage(login,passwd,wikiurl,wikimagename,outputdir):
    """ download an image from wiki server """
    os.system(r'curl -d "wpName='+login+\
            r'&wpPassword='+passwd+\
            r'&wpRemember=1&wpLoginattempt=Log%20in" "'+wikiurl+\
            r'index.php?title=Special:Userlogin&amp;'+\
            r'action=submitlogin&amp;type=login" -c cookies.txt')
    out = os.popen(r'curl -b cookies.txt "'+wikiurl+\
            r'/index.php?title=Image:'+wikimagename+r'"')
    html = ""
    for line in out:
        html = html + line
    wikipage = xml.dom.minidom.parseString(html)
    text = wikipage.getElementsByTagName("img")
    for tag in text:
        print "\033[38;1mImage:"+wikimagename+"\033[0m"
        if tag.getAttribute("alt") == "Image:"+wikimagename.replace("_"," "):
            urlimage = tag.getAttribute("src")
            urlimage = "/".join(urlimage.split("/")[2:])
            # we don't wanna thumb !
            if re.search(r'\/thumb\/',urlimage):
                urlimage = re.sub(r'\/thumb\/',"//",urlimage)
                urlimage = "/".join(urlimage.split("/")[:-1])
            print "\033[34;4m"+urlimage+"\033[0m"
    os.system(r'curl -o '+outputdir+"/"+IMGDIR+wikimagename+r' '+wikiurl+urlimage)
    print "\033[38;1m"+r'curl -o '+outputdir+"/"+IMGDIR+wikimagename+r' '+wikiurl+urlimage+"\033[0m"

def figure(line,cmpt_figure,login,passwd,wikiurl,outputdir):
    """ define figure from wiki line:
    [[image:POD.png|center|frame|200px|'''figure 1''' - ''Description fonctionnelle du système'']]
    """
    if not re.match(r'^\[\[image',line):
        raise Exception, "image wiki line malformed"
    out = r'\begin{figure}[H]'+"\n"
    out = out + r'\center'+"\n"
    out = out + r'\includegraphics[width=0.6 \textwidth]{'
    m = re.search(r'^\[\[[i|I]mage:(.*?)\|.*',line)
    wikimagename = m.group(1)
    wikimagename =  wikimagename[0].upper()[0] + wikimagename[1:]
    out = out +IMGDIR+ wikimagename + "}\n"
    getWikimage(login,passwd,wikiurl,wikimagename,outputdir)
    print "\033[38;1mFigure "+m.group(1)+" copied\033[0m"
    m = re.search(r'.*\'\'(.*?)\'\'\]\]',line)
    out = out + r'\caption{'+m.group(1) +'}\n'
    out = out + r'\label{figure'+str(cmpt_figure)+'}\n' 
    out = out + r'\end{figure}'+'\n'
    return out

def wikitolatex(input,output,login,passwd,wikiurl,outputdir):
    """ this function convert wiki syntax in latex syntax """
    source = 0
    tabular=0
    item = 0
    cmpt_figure = 0

    for line in input.split('\n'):
            line = line.encode('utf-8')
            # ignore [[PODintro tag
            if re.match(r'\[\[PODintro.*',line):
                continue
            # verbatim
            if re.match(r'^\s*<source',line) and source == 0:
                output.write(r'\begin{lstlisting}[language=XML,style=wiki]'+'\n')
                source = 1
            elif source == 1:
                if re.match(r'^\s*</source',line):
                    source =0
                    output.write(r'\end{lstlisting}'+'\n')
                else:
                    output.write(line+'\n')
            elif re.match(r'^\{\|',line):
                tabular = 1
            elif tabular == 1:
                if re.match(r'^\|\}',line):
                    tabular = 0
            # image
            elif re.match(r'^\[\[image',line):
                output.write(figure(line,cmpt_figure,login,passwd,wikiurl,outputdir))
                cmpt_figure = cmpt_figure +1
            else:
                out = line
                # for chapter,section,subsection,...
                out = re.sub(r'^\s*(=+)\s*(.*?)\s*\1$',\
                        lambda m: '\\'+\
                        ('chapter','section','subsection','subsubsection','paragraph')[len(m.group(1))-1]+\
                        '{'+m.group(2)+'}',out)
                # for bold
                out = re.sub(r"(\'\'+)\s*(.*?)\s*(\'\'+)",\
                        lambda m: (len(m.group(3))!=len(m.group(1)) and '\'' or '')\
                        +((len(m.group(3))==1) and m.group(2) or (
                        '\\'+('pouet','emph','textbf','','','')[len(m.group(3))-1]+\
                                '{'+m.group(2)+'}'))
                        ,out)

                # for dollar
                out = re.sub(r'\$',r'\\$',out)
                # for tag
                out = re.sub(r'<(.*?)>',
                        lambda m:r'\verb$<'+m.group(1)+'>$',out)
                # for links with title
                out = re.sub(r'\[(http\:.*?html)\s(.*?)\]',\
                        lambda m:r'\htmladdnormallink{'+m.group(1)+r'}{'+m.group(2)+r'}',out)
       
                # for itemize
                if re.match(r'^\*',out) and item==0:
                    output.write(r'\begin{itemize}'+'\n')
                    item=1
                if re.match(r'^\*\*',out) and item==1:
                    output.write(r'\begin{itemize}'+'\n')
                    item=2
                if item==2 and not re.match(r'^\*\*',out):
                    output.write(r'\end{itemize}'+'\n')
                    item=1
                if item==1 and not re.match(r'^\*',out):
                     output.write(r'\end{itemize}'+'\n')
                     item=0
                out = re.sub(r'^\*.+?','\item ',out)
        
                # for underscore
                out = re.sub(r'\_',r'\\_',out)
                # for sharp
                out = re.sub(r'#',r'\\#',out)
               
                # write output
                output.write(out+'\n')

def getText(nodelist):
    """ return the wiki text find in html node page """
    rc = ""
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
           rc = rc + node.data
    return rc

def getWikipage(login,passwd,wikiurl,wikipage):
    """ This function return the text of given wikipage in wiki syntax"""
    os.popen(r'curl -d "wpName='+login+\
            r'&wpPassword='+passwd+\
            r'&wpRemember=1&wpLoginattempt=Log%20in" "'+wikiurl+\
            r'index.php?title=Special:Userlogin&amp;'+\
            r'action=submitlogin&amp;type=login" -c cookies.txt')
    out = os.popen(r'curl -b cookies.txt "'+wikiurl+\
            r'index.php?title='+wikipage+r'&action=edit"')
    html = ""
    for line in out:
        html = html + line

    wikipage = xml.dom.minidom.parseString(html)
    text = wikipage.getElementsByTagName("textarea")
    text = text[0]
    return getText(text.childNodes)

def fillTemplate(templatefilename,outputdir):
    ftemplate = open(templatefilename,"r")
    os.popen("mkdir -p "+outputdir+"/"+IMGDIR)
    flatex = open(outputdir+"/index.tex","w")
    
    for line in ftemplate:
            # if tag wiki is found 
            if re.match(r'^\s*<wikinclude',line):
                # get the tag
                tree = xml.dom.minidom.parseString(line)
                balise = tree.getElementsByTagName("wikinclude")[0]
                # get wiki page in wiki syntax
                out = getWikipage(balise.getAttribute("login"),\
                                  balise.getAttribute("passwd"),\
                                  balise.getAttribute("wikiurl"),\
                                  balise.getAttribute("wikipage"))
                latexout = open(outputdir+"/"+balise.getAttribute("wikipage").replace(r'%','')+\
                        ".tex","w")
                # Convert wiki syntax in Latex syntax
                wikitolatex(out,
                            latexout,
                            balise.getAttribute("login"),
                            balise.getAttribute("passwd"),
                            balise.getAttribute("wikiurl"),
                            outputdir) 
                # write \input command for latex file generated
                flatex.write(r'\input{'+\
                        balise.getAttribute("wikipage").replace(r'%','')+\
                        ".tex"+'}')
            else:
                flatex.write(line)

#####################################
# main
#####################################
if len(sys.argv) != 3:
    print len(sys.argv)
    print "Argument error\nQDWL templatefilename.tex latexfilename.tex\n"
    exit(0)

fillTemplate(sys.argv[1],sys.argv[2])

